import subprocess
from apscheduler.schedulers.background import BackgroundScheduler
from django_apscheduler.jobstores import (
    DjangoJobStore, 
    register_events, 
    register_job)
from computes.models import Compute
from instances.models import Instance
from libvirtmgr.hostdetails import wvmHostDetails
from libvirtmgr.storage import wvmStorages
from decimal import Decimal,ROUND_HALF_UP
from django.core.cache import cache


LogTag = '------Debug------'
# 实例化调度器
scheduler = BackgroundScheduler()
# 调度器使用DjangoJobStore()
scheduler.add_jobstore(DjangoJobStore(), "default")

@register_job(scheduler, "interval", seconds=25, replace_existing=True)
# 首页Dashboard统计
def dashboard_cache():
    cache_json={}
    instances_list=[]
    compute_info=Compute.objects.all()
    # 计算节点总数量
    comp_count=compute_info.count()
    cache_json['comp_count']=comp_count
    connection_count=0
    for sub_comp in compute_info:
        if len(sub_comp.hostname)==0:
            sub_comp.hostname="127.0.0.1"
        if is_connection(sub_comp.hostname):
            connection_count=connection_count+1
    # 计算节点在线数量
    comp_online=connection_count
    cache_json['comp_online']=comp_online
    # 计算节点离线数量
    comp_offline = comp_count-comp_online
    cache_json['comp_offline']=comp_offline
    
    # 云主机数量
    instances = Instance.objects.all()
    inst_count = instances.count()
    cache_json['inst_count']=inst_count
    for instance in instances:
        instance_json={}
        instance_json['id']=instance.id
        instance_json['name']=instance.name
        instance_json['remarks']=instance.remarks
        instance_json['status']=instance.proxy.instance.info()[0]
        instance_json['vcpu']=instance.proxy.instance.info()[3]
        instance_json['cur_memory']=instance.cur_memory
        instance_json['disk']=round((instance.proxy.get_disk_devices()[0]['size'] / 1073741824), 2)
        instance_json['cpu_usage']=round(instance.proxy.cpu_usage()['cpu'],2)
        if instance.proxy.mem_usage()['total'] !=0:
            instance_json['mem_usage']=round(instance.proxy.mem_usage()['used'] / instance.proxy.mem_usage()['total'],2)
        else:
            instance_json['mem_usage']=0
        instance_json['disk_usage']=round((instance.proxy.get_disk_devices()[0]['used'] / instance.proxy.get_disk_devices()[0]['size'])*100,2)
        instances_list.append(instance_json)
    cache_json['instances']=instances_list
        
    # 开机（激活）
    instance_acitvecount=0
    # 关机
    instance_closecount=0
    # 挂起
    instance_pausecount=0
    cpu_usage = 0
    mem_usage = 0
    blk_usage = 0
    for sub in instances:
        if sub.proxy.instance.info()[0]==1:
            instance_acitvecount=instance_acitvecount+1
        if sub.proxy.instance.info()[0]==3:
            instance_pausecount=instance_pausecount+1
        if sub.proxy.instance.info()[0]==5:
            instance_closecount=instance_closecount+1
        cpu_usage = cpu_usage+sub.proxy.instance.info()[3]
        mem_usage = mem_usage+sub.proxy.instance.info()[2]
        device_info=sub.proxy.get_disk_devices()
        for sub_blk_usage in device_info:
            blk_usage = blk_usage+sub_blk_usage['size']
        if device_info:
            device_info[0]['size']=device_info[0]['size']/1024/1024/1024
    
    cache_json['instance_acitvecount']=instance_acitvecount
    cache_json['instance_closecount']=instance_closecount
    cache_json['instance_pausecount']=instance_pausecount
    
            
    # 资源池CPU总量
    vcpu_count=0
    # 资源池内存总量
    vmem_count=0
    # 资源池磁盘总量
    vdsk_count=0
    
    for compute in compute_info:
        instances_conn = wvmHostDetails(
        compute.hostname,
        compute.login,
        compute.password,
        compute.type,
        )
        host_info=instances_conn.get_node_info()
        vcpu_count=vcpu_count+host_info[3]
        vmem_count=vmem_count+host_info[2]
        vdsk_count=vdsk_count+host_info[2]
        storage_conn=wvmStorages(
            compute.hostname, compute.login, compute.password, compute.type
        )
        storage_info=storage_conn.get_storages_info()
        for storage in storage_info:
            vdsk_count=vdsk_count+storage['size']
    cpu_usage_display=round(cpu_usage,2)
    cache_json['cpu_usage_display']=cpu_usage_display
    mem_usage_display=round(mem_usage/1024/1024,2)
    cache_json['mem_usage_display']=mem_usage_display
    vmem_count_display=round(vmem_count/1024/1024/1024,2)
    cache_json['vmem_count_display']=vmem_count_display
    vdsk_count_display=round(vdsk_count/1024/1024/1024,2)
    cache_json['vdsk_count_display']=vdsk_count_display
    blk_usage_display = round(blk_usage/1024/1024/1024,2)
    cache_json['blk_usage_display']=blk_usage_display
    cpu_perc=str(round_dec(round(cpu_usage/vcpu_count,4)*100,2))+'%'
    cache_json['cpu_perc']=cpu_perc
    mem_perc=str(round_dec(round((mem_usage*1024)/vmem_count,4)*100,2))+'%'
    cache_json['mem_perc']=mem_perc
    disk_perc=str(round_dec(round(blk_usage/vdsk_count,4)*100,2))+'%'
    cache_json['disk_perc']=disk_perc
    cache.set('dashboard', cache_json, timeout=60)  # 设置缓存过期时间为20秒
    
    
def round_dec(n,d):
  s = '0.' + '0' * d
  return Decimal(str(n)).quantize(Decimal(s),ROUND_HALF_UP)
    
    
def is_connection(host):
    result = subprocess.run(
        ['ping', '-c', '3', '-W', '5', host],
        capture_output=True,
        encoding='utf8'
    )
    if result.returncode == 0:
        return True
    else:
        return False

register_events(scheduler)
scheduler.start()